package ar.edu.itba.pod.legajo47573;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;

import org.joda.time.Duration;

import ar.edu.itba.balance.api.AgentsBalancer;
import ar.edu.itba.balance.api.NodeAgent;
import ar.edu.itba.balance.api.NotCoordinatorException;
import ar.edu.itba.node.Node;
import ar.edu.itba.node.NodeInformation;
import ar.edu.itba.pod.agent.market.Consumer;
import ar.edu.itba.pod.agent.market.Market;
import ar.edu.itba.pod.agent.market.Producer;
import ar.edu.itba.pod.agent.market.Resource;
import ar.edu.itba.pod.time.TimeMapper;
import ar.edu.itba.pod.time.TimeMappers;

public class MySimulationApp implements Runnable {
	
	private static String id;
	private static String host;
	private static int port;
	private static String remoteHost;
	private static int remotePort;
	
	public static void main(String[] args) {
		id = args[0];
		host = args[1];
		port = Integer.valueOf(args[2]);
		if(!id.equals("a")){
			remoteHost = args[3];
			remotePort = Integer.valueOf(args[4]);
		}
		new MySimulationApp().run();
	}

	@Override
	public void run() {

		NodeInformation info = new NodeInformation(host, port, id);
		TimeMapper timeMapper = TimeMappers.oneSecondEach(Duration.standardHours(10));
		
		final MyNode node = new MyNode(info, timeMapper);
		Thread thread = new Thread(node);
		thread.start();
		
		Resource steel = new Resource("Alloy", "Steel");
		Resource gold = new Resource("Mineral", "Gold");

		int i = 1;
		
		if(id.equals("a")){
			try {
				node.getCluster().createGroup();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

            node.getSimulation().add(new Market("A gold market1", gold));
            node.getSimulation().add(new Producer("A gold mine1", gold, Duration.standardHours(1), 4));

            node.getSimulation().add(new Consumer("A gold consumer1", gold, Duration.standardHours(1), 4));

//            node.getSimulation().add(new Consumer("gold consumer2", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer3", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer4", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer5", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer6", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer7", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer8", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer9", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer10", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer11", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer12", gold, Duration.standardHours(1), 4));
//            node.getSimulation().add(new Consumer("gold consumer13", gold, Duration.standardHours(1), 4));
//			node.getSimulation().add(new Consumer("gold consumer" + 1, gold, Duration.standardDays(1), 2));
//			node.getSimulation().add(new Consumer("steel consumer" + 1, steel, Duration.standardDays(1), 2));
//			node.getSimulation().add(new Producer("steel mine" + 1, steel, Duration.standardDays(1), 5));
//			node.getSimulation().add(new Producer("steel mine" + 2, steel, Duration.standardDays(1), 5));
////			node.getSimulation().add(new Producer("steel mine" + 3, steel, Duration.standardDays(1), 5));
//			node.getSimulation().add(new Market("steel market", steel));
		}
		else if(id.equals("b")){
			try {
				node.getCluster().connectToGroup(remoteHost, remotePort);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NotBoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
			
			 node.getSimulation().add(new Market("B steel market", steel));
				node.getSimulation().add(new Consumer("B steel consumer" + 1, steel, Duration.standardHours(1), 2));
				node.getSimulation().add(new Producer("B steel mine" + 1, steel, Duration.standardHours(1), 1));
//		}
//			node.getSimulation().add(new Market("gold market2", gold));
//			node.getSimulation().add(new Market("steel market14", steel));
//			node.getSimulation().add(new Consumer("gold consumer8", gold, Duration.standardHours(1), 4));
//			node.getSimulation().add(new Consumer("steel consumer" + 10, steel, Duration.standardHours(1), 2));
//			node.getSimulation().add(new Producer("steel mine" + 1, steel, Duration.standardHours(1), 1));
			
			
////			node.getSimulation().add(new Consumer("gold consumer" + 1, gold, Duration.standardDays(2), 4));
//			node.getSimulation().add(new Consumer("steel consumer" + 1, steel, Duration.standardDays(1), 2));
//			node.getSimulation().add(new Producer("gold mine" + 1, gold, Duration.standardDays(1), 1));
////			node.getSimulation().add(new Market("gold market", gold));
			}
		else if(id.equals("c")){
			try {
				node.getCluster().connectToGroup(remoteHost, remotePort);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NotBoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			node.getSimulation().add(new Consumer("C steel consumer" + 2, steel, Duration.standardHours(1), 2));
			node.getSimulation().add(new Consumer("C steel consumer" + 1, steel, Duration.standardHours(1), 2));
			node.getSimulation().add(new Producer("C steel mine" + 1, steel, Duration.standardHours(1), 1));
			node.getSimulation().add(new Market("C steel market", steel));
		//	node.getSimulation().add(new Producer("gold mine" + 4, gold, Duration.standardDays(1), 1));
		//	node.getSimulation().add(new Consumer("steel consumer" + 1, steel, Duration.standardDays(1), 2));
			
			/***********************************************************/
			Thread thread1 = new Thread(){
				public void run(){
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					try {
						System.out.println("SHUTTING DOWN");
						//				boolean caca = true;
						//				while(caca){
						AgentsBalancer balancer = (AgentsBalancer)Registries.getRemoteObject(node, node.getCoordinator(), Node.AGENTS_BALANCER);
						System.out.println(node.getSimulation().agentsRunning());
						List<NodeAgent> nodeAgents = node.getTransfer().stopAndGet(node.getSimulation().agentsRunning());
						//				if(balancer != null){
						balancer.shutdown(nodeAgents);
						try {
							node.getCluster().disconnectFromGroup(node.getInfo());
							//node.interrupt();
						} catch (NotBoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						//				caca = false;
						//				}
						//				}
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (NotCoordinatorException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			};
			thread1.start();
			/***********************************************************/
			//node.getSimulation().add(new Consumer("steel consumer" + 2, steel, Duration.standardDays(1), 2));
//			node.getSimulation().add(new Consumer("gold consumer" + 1, gold, Duration.standardDays(2), 4));
//			node.getSimulation().add(new Producer("gold mine" + 1, gold, Duration.standardDays(1), 1));
		}
		else {
			try {
				node.getCluster().connectToGroup(remoteHost, remotePort);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NotBoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		System.out.println("Starting ...");
		//try {
//			node.getSimulation().startAndWait(Duration.standardMinutes(10));
			node.getSimulation().start(Duration.standardMinutes(10));
	//	} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		System.out.println("Ending ...");
	}

}
